﻿using System.Windows;
using Caliburn.Micro;
using SS.Common.Logging;
using SS.WPF.Framework.Preference;
using SS.WPF.Framework.ViewModel.Screen;

namespace SS.WPF.Framework.Display.MsgBox.ViewModels
{
    using System;

    /// <summary>
    /// View model logic for <see cref="MsgBoxViewModel"/>
    /// </summary>
    public class MsgBoxViewModel : DialogViewModelBase
    {
        #region Fields

        private static readonly ILogger Logger = LoggerManager.GetLogger(typeof(MsgBoxViewModel).Name);

        #endregion

        #region Properties

        public bool IsOKCancelable { get; private set; }

        /// <summary>
        /// Gets message box information
        /// </summary>
        public MsgBoxInfo Info { get; private set; }

        /// <summary>
        /// Gets a value indicating whether cancel button is visible
        /// </summary>
        public bool IsCancel
        {
            get
            {
                return this.Info.Buttons == MsgBoxButtons.OKCancel
                    | (this.Info.Buttons == MsgBoxButtons.YesNoCancel);
            }
        }

        public bool IsCancelDefault { get; private set; }

        public IPreferenceService PreferenceService
        {
            get
            {
                return IoC.Get<IPreferenceService>();
            }
        }

        /// <summary>
        /// Gets a value indicating whether error image is visible
        /// </summary>
        public bool IsError
        {
            get
            {
                return this.Info.Image == MsgBoxImage.Error;
            }
        }

        /// <summary>
        /// Gets a value indicating whether information image is visible
        /// </summary>
        public bool IsInformation
        {
            get
            {
                return this.Info.Image == MsgBoxImage.Information;
            }
        }

        /// <summary>
        /// Gets a value indicating whether no button is visible
        /// </summary>
        public bool IsNo
        {
            get
            {
                return (this.Info.Buttons == MsgBoxButtons.YesNo)
                    || (this.Info.Buttons == MsgBoxButtons.YesNoCancel);
            }
        }

        /// <summary>
        /// Gets a value indicating whether ok button is visible
        /// </summary>
        public bool IsNoDefault
        {
            get
            {
                return this.Info.Buttons == MsgBoxButtons.YesNo;
            }
        }

        /// <summary>
        /// Gets a value indicating whether ok button is visible
        /// </summary>
        public bool IsOk
        {
            get
            {
                return (this.Info.Buttons == MsgBoxButtons.OK) || (this.Info.Buttons == MsgBoxButtons.OKCancel);
            }
        }

        /// <summary>
        /// Gets a value indicating whether question image is visible
        /// </summary>
        public bool IsQuestion
        {
            get
            {
                return this.Info.Image == MsgBoxImage.Question;
            }
        }

        /// <summary>
        /// Gets a value indicating whether warning image is visible
        /// </summary>
        public bool IsWarning
        {
            get
            {
                return this.Info.Image == MsgBoxImage.Warning;
            }
        }

        /// <summary>
        /// Gets a value indicating whether yes button is visible
        /// </summary>
        public bool IsYes
        {
            get
            {
                return (this.Info.Buttons == MsgBoxButtons.YesNo) || (this.Info.Buttons == MsgBoxButtons.YesNoCancel);
            }
        }

        /// <summary>
        /// Gets message box shown result
        /// </summary>
        public MsgBoxResult Result { get; private set; }

        private Visibility _confirmVisibility;
        public Visibility ConfirmVisibility
        {
            get
            {
                return this._confirmVisibility;
            }
            set
            {
                this._confirmVisibility = value;
                this.NotifyOfPropertyChange(() => this.ConfirmVisibility);
            }
        }

        private bool _isNotShowAgain;

        public bool IsNotShowAgain
        {
            get
            {
                return this._isNotShowAgain;
            }
            set
            {
                this._isNotShowAgain = value;
                this.NotifyOfPropertyChange(() => this.IsNotShowAgain);
            }
        }

        #endregion

        #region Constructors and Destructors

        /// <summary>
        /// Initializes a new instance of the <see cref="MsgBoxViewModel"/> class.
        /// </summary>
        /// <param name="info">
        /// The message box information
        /// </param>
        public MsgBoxViewModel(MsgBoxInfo info)
        {
            this.Info = info;
            var result = MsgBoxResult.OK;
            switch (info.Buttons)
            {
                case MsgBoxButtons.OK:
                    this.ConfirmVisibility = Visibility.Collapsed;
                    IsOKCancelable = true;
                    result = MsgBoxResult.OK;
                    break;
                case MsgBoxButtons.OKCancel:
                    result = MsgBoxResult.Cancel;
                    break;
                case MsgBoxButtons.YesNo:
                    IsCancelDefault = true;
                    result = MsgBoxResult.No;
                    break;
                case MsgBoxButtons.YesNoCancel:
                    result = MsgBoxResult.Cancel;
                    break;
            }

            if (!info.StorePreference)
            {
                this.ConfirmVisibility = Visibility.Collapsed;
            }

            this.Result = result;
        }

        #endregion

        #region Public Methods

        /// <summary>
        /// Handle button clicked event
        /// </summary>
        /// <param name="id">
        /// The button id
        /// </param>
        /// <param name="close">
        /// Close dialog with result set to true
        /// </param>
        public void Click(int id, bool close)
        {
            try
            {
                this.Result = (MsgBoxResult)id;
                if (this.Result == MsgBoxResult.Yes || this.Result == MsgBoxResult.OK)
                {
                    if (this.IsNotShowAgain && !string.IsNullOrEmpty(this.Info.PreferenceKey))
                    {
                        PreferenceService.GetPreferenceStore(this.GetType().Name).SetValue(this.Info.PreferenceKey, this.IsNotShowAgain);
                    }
                }
            }
            catch (Exception ex)
            {
                Logger.Error("Exception occurs", ex);
            }
            finally
            {
                this.SetDialogResult(close);
            }
        }

        #endregion
    }
}
